const dayjs = require('dayjs');
/**
 * 测试辅助工具
 * 用于研发流程状态机测试
 */

/**
 * 模拟角色系统
 */
const MockRoles = {
  // 默认角色为软件工程师
  currentRole: 'software_engineer',
  
  // 所有可用角色列表 - 统一角色ID和名称
  availableRoles: [
    { code: 'admin', name: '系统管理员' },
    { code: 'business_staff', name: '业务人员' },
    { code: 'director', name: '董事长' },
    { code: 'research_manager', name: '研发经理' },
    { code: 'hardware_engineer', name: '硬件工程师' },
    { code: 'software_engineer', name: '软件工程师' },
    { code: 'purchaser', name: '采购人员' },
    { code: 'sample_team', name: '样品组' },
    { code: 'tester', name: '测试人员' },
    { code: 'receptionist', name: '前台人员' },
    { code: 'warehouse_keeper', name: '仓库人员' },
    { code: 'document_controller', name: '文控' },
    { code: 'secretary', name: '文秘人员' },
    { code: 'production_supervisor', name: '生产主管' },
    { code: 'production_engineer', name: 'PE工程师' },
    { code: 'sample_manager', name: '样品管理员' }
  ],
  
  // 全局调试模式开关
  debugMode: false,
  
  // 模拟角色配置
  config: {
    // 权限验证延迟（毫秒）
    permissionCheckDelay: 0,
    
    // 自动记录角色切换操作
    autoLog: true,
    
    // 日志最大条数
    maxLogEntries: 100,
    
    // 自动保存到存储
    autoSave: true
  },
  
  /**
   * 切换当前测试角色
   * @param {String} role 角色ID
   * @returns {String} 设置后的角色ID
   */
  switchRole(role) {
    // 验证角色是否存在
    if (!this.availableRoles.some(r => r.code === role)) {
      console.warn(`[测试模式] 无效角色ID: ${role}`);
      return this.currentRole;
    }
    
    this.currentRole = role;
    
    // 保存到本地存储
    if (this.config.autoSave) {
      wx.setStorageSync('DEBUG_CURRENT_ROLE', role);
      
      // 更新角色模拟系统的当前角色
      wx.setStorageSync('current_simulated_role', role);
    }
    
    // 创建模拟记录
    const simulationRecord = {
      role: role,
      roleName: this._getRoleName(role),
      timestamp: dayjs().valueOf(),
      userName: '当前用户',
      action: 'SWITCH_ROLE'
    };
    
    // 保存记录
    if (this.config.autoLog) {
      this._logRoleAction(simulationRecord);
    }
    
    // 检查调试模式是否启用
    const isDebugEnabled = this.isDebugModeEnabled();
    
    // 只有在调试模式已启用的情况下才设置状态
    if (isDebugEnabled) {
      try {
        const ResearchStateBiz = require('../../miniprogram/projects/oa/biz/research_state_biz.js');
        // 保持当前状态，不自动启用
      } catch (e) {
        console.error('[测试模式] 无法加载研发状态业务逻辑模块', e);
      }
    }
    
    // 显示切换成功提示
    wx.showToast({
      title: `已切换为: ${this._getRoleName(role)}`,
      icon: 'none',
      duration: 2000
    });
    
    // 尝试通知当前页面更新权限状态
    this._notifyPageUpdate();
    
    console.log(`[测试模式] 当前角色已切换为: ${role}`);
    return role;
  },
  
  /**
   * 通知当前页面更新权限状态
   * @private
   */
  _notifyPageUpdate() {
    try {
      const currentPages = getCurrentPages();
      if (currentPages && currentPages.length > 0) {
        const currentPage = currentPages[currentPages.length - 1];
        
        // 如果页面有_updateFlowPermission方法，调用它
        if (currentPage) {
          if (typeof currentPage._updateFlowPermission === 'function') {
            console.log('[测试模式] 通知页面更新权限状态');
            setTimeout(() => {
              currentPage._updateFlowPermission();
            }, 300);
          }
          
          // 触发页面自定义事件
          if (typeof currentPage.triggerEvent === 'function') {
            currentPage.triggerEvent('roleChange', {
              role: this.currentRole,
              roleName: this._getRoleName(this.currentRole)
            });
          }
        }
      }
    } catch (e) {
      console.error('[测试模式] 通知页面更新失败', e);
    }
  },
  
  /**
   * 记录角色操作日志
   * @param {Object} record 日志记录
   * @private
   */
  _logRoleAction(record) {
    try {
      const logs = wx.getStorageSync('ROLE_SIMULATION_LOGS') || [];
      logs.unshift(record);
      
      // 最多保留指定条数的日志
      if (logs.length > this.config.maxLogEntries) {
        logs.length = this.config.maxLogEntries;
      }
      
      wx.setStorageSync('ROLE_SIMULATION_LOGS', logs);
      
      // 如果是切换角色，保存最近的模拟记录
      if (record.action === 'SWITCH_ROLE') {
        wx.setStorageSync('last_role_simulation', record);
      }
    } catch (e) {
      console.error('[测试模式] 记录角色操作日志失败', e);
    }
  },
  
  /**
   * 获取当前测试角色
   * @returns {String} 当前角色ID
   */
  getCurrentRole() {
    // 优先使用角色模拟系统的设置
    const simulatedRole = wx.getStorageSync('current_simulated_role');
    if (simulatedRole) {
      return simulatedRole;
    }
    
    return wx.getStorageSync('DEBUG_CURRENT_ROLE') || this.currentRole;
  },
  
  /**
   * 获取模拟角色ID
   * @returns {String} 当前模拟角色ID
   */
  getSimulatedRole() {
    if (!this.isDebugModeEnabled()) return '';
    
    return this.getCurrentRole();
  },
  
  /**
   * 获取模拟角色完整信息
   * @returns {Object} 角色信息对象
   */
  getSimulatedRoleInfo() {
    const roleId = this.getCurrentRole();
    return {
      roleId: roleId,
      roleName: this._getRoleName(roleId),
      isDebugMode: this.isDebugModeEnabled()
    };
  },
  
  /**
   * 获取所有可用角色
   * @returns {Array} 角色列表
   */
  getAllRoles() {
    try {
      // 优先尝试从角色配置中获取
      const roleConfig = require('../../miniprogram/projects/oa/config/research_role_config.js');
      if (roleConfig && roleConfig.ROLES) {
        return roleConfig.ROLES;
      }
    } catch (e) {
      // 配置不存在，使用内置角色列表
    }
    
    return this.availableRoles.map(role => ({
      id: role.code,
      name: role.name
    }));
  },
  
  /**
   * 检查是否拥有指定角色
   * @param {String} role 角色ID
   * @returns {Boolean} 是否拥有角色
   */
  hasRole(role) {
    const currentRole = this.getCurrentRole();
    
    // 管理员拥有所有权限
    if (currentRole === 'admin') {
      return true;
    }
    
    return currentRole === role;
  },
  
  /**
   * 检查是否拥有指定角色之一
   * @param {Array} roles 角色ID数组
   * @returns {Boolean} 是否拥有角色
   */
  hasAnyRole(roles = []) {
    const currentRole = this.getCurrentRole();
    
    // 管理员拥有所有权限
    if (currentRole === 'admin') {
      return true;
    }
    
    return roles.includes(currentRole);
  },
  
  /**
   * 重置角色为默认值
   */
  resetRole() {
    this.currentRole = 'software_engineer';
    
    if (this.config.autoSave) {
      wx.removeStorageSync('DEBUG_CURRENT_ROLE');
      
      // 清除角色模拟系统的设置
      wx.removeStorageSync('current_simulated_role');
    }
    
    // 记录重置操作
    if (this.config.autoLog) {
      this._logRoleAction({
        role: 'reset',
        roleName: '重置角色',
        timestamp: dayjs().valueOf(),
        userName: '当前用户',
        action: 'RESET_ROLE'
      });
    }
    
    // 通知页面更新
    this._notifyPageUpdate();
    
    console.log('[测试模式] 角色已重置为默认值');
  },
  
  /**
   * 开启调试模式
   */
  enableDebugMode() {
    this.debugMode = true;
    wx.setStorageSync('DEBUG_MODE_ENABLED', true);
    
    // 记录开启操作
    if (this.config.autoLog) {
      this._logRoleAction({
        role: this.getCurrentRole(),
        roleName: this._getRoleName(this.getCurrentRole()),
        timestamp: dayjs().valueOf(),
        userName: '当前用户',
        action: 'ENABLE_DEBUG_MODE'
      });
    }
    
    // 尝试加载并开启角色模拟配置
    try {
      const ResearchStateBiz = require('../../miniprogram/projects/oa/biz/research_state_biz.js');
      ResearchStateBiz.ROLE_SIMULATION.ENABLED = true;
    } catch (e) {
      console.error('[测试模式] 无法加载研发状态业务逻辑模块', e);
    }
    
    // 通知页面更新
    this._notifyPageUpdate();
    
    console.log('[测试模式] 已开启');
  },
  
  /**
   * 关闭调试模式
   */
  disableDebugMode() {
    this.debugMode = false;
    wx.removeStorageSync('DEBUG_MODE_ENABLED');
    
    // 记录关闭操作
    if (this.config.autoLog) {
      this._logRoleAction({
        role: this.getCurrentRole(),
        roleName: this._getRoleName(this.getCurrentRole()),
        timestamp: dayjs().valueOf(),
        userName: '当前用户',
        action: 'DISABLE_DEBUG_MODE'
      });
    }
    
    // 尝试加载并关闭角色模拟配置
    try {
      const ResearchStateBiz = require('../../miniprogram/projects/oa/biz/research_state_biz.js');
      ResearchStateBiz.ROLE_SIMULATION.ENABLED = false;
    } catch (e) {
      console.error('[测试模式] 无法加载研发状态业务逻辑模块', e);
    }
    
    // 清除角色模拟
    this.resetRole();
    
    // 通知页面更新
    this._notifyPageUpdate();
    
    console.log('[测试模式] 已关闭');
  },
  
  /**
   * 检查调试模式是否开启
   * @returns {Boolean} 是否开启
   */
  isDebugModeEnabled() {
    return wx.getStorageSync('DEBUG_MODE_ENABLED') === true;
  },
  
  /**
   * 清空角色模拟日志
   * @returns {Boolean} 操作是否成功
   */
  clearLogs() {
    try {
      wx.removeStorageSync('ROLE_SIMULATION_LOGS');
      return true;
    } catch (e) {
      console.error('[测试模式] 清空日志失败', e);
      return false;
    }
  },
  
  /**
   * 获取权限检查结果
   * @param {String} permission 权限标识
   * @returns {Boolean} 是否有权限
   */
  hasPermission(permission) {
    try {
      const roleConfig = require('../../miniprogram/projects/oa/config/research_role_config.js');
      return roleConfig.hasPermission(this.getCurrentRole(), permission);
    } catch (e) {
      console.error('[测试模式] 检查权限失败', e);
      // 默认允许访问
      return true;
    }
  },
  
  /**
   * 获取角色名称
   * @param {String} roleCode 角色ID
   * @returns {String} 角色名称
   * @private
   */
  _getRoleName(roleCode) {
    try {
      // 尝试从角色配置中获取
      const roleConfig = require('../../miniprogram/projects/oa/config/research_role_config.js');
      if (roleConfig && roleConfig.getRoleName) {
        return roleConfig.getRoleName(roleCode);
      }
    } catch (e) {
      // 配置不存在，使用内置角色列表
    }
    
    const role = this.availableRoles.find(r => r.code === roleCode);
    return role ? role.name : roleCode;
  }
};

/**
 * 创建测试项目
 * @returns {Object} 测试项目数据
 */
function createTestProject() {
  const id = 'test_' + dayjs().valueOf();
  const testProject = {
    _id: id,
    RESEARCH_TITLE: '测试研发项目',
    RESEARCH_CODE: 'TEST-' + id.substring(5, 10),
    RESEARCH_STATUS: 3, // 活动状态
    RESEARCH_ACTIVE_STATE: 'hardware_design_sample',
    RESEARCH_SUB_STATE: 'hw_design',
    RESEARCH_DESC: '这是一个测试项目，用于调试',
    RESEARCH_ADD_TIME: dayjs().valueOf(),
    RESEARCH_START_DATE: dayjs().valueOf(),
    RESEARCH_END_DATE: dayjs().valueOf() + 30 * 24 * 60 * 60 * 1000,
    RESEARCH_USER_ID: getCurrentUser()?.id || 'test_user',
    RESEARCH_USER_NAME: getCurrentUser()?.name || '测试用户',
    IS_TEST_DATA: true
  };
  
  // 保存到缓存
  const cacheHelper = require('./cache_helper.js');
  const cacheKey = 'CACHE_OA_RESEARCH_DETAIL_' + id;
  cacheHelper.set(cacheKey, testProject, 60 * 60 * 1000); // 缓存1小时
  
  console.log('[测试] 创建测试项目成功:', testProject);
  return testProject;
}

/**
 * 获取模拟用户角色
 * @returns {String} 当前模拟的角色
 */
function getSimulatedRole() {
  const key = '__TEST_SIMULATED_ROLE';
  const cacheHelper = require('./cache_helper.js');
  return cacheHelper.get(key) || '';
}

/**
 * 设置模拟用户角色
 * @param {String} role 角色代码
 */
function setSimulatedRole(role) {
  const key = '__TEST_SIMULATED_ROLE';
  const cacheHelper = require('./cache_helper.js');
  cacheHelper.set(key, role, 24 * 60 * 60 * 1000); // 缓存1天
  console.log('[测试] 设置模拟角色:', role);
}

// 导出模块
module.exports = {
  // 角色管理
  switchRole: MockRoles.switchRole.bind(MockRoles),
  getCurrentRole: MockRoles.getCurrentRole.bind(MockRoles),
  getAllRoles: MockRoles.getAllRoles.bind(MockRoles),
  getAvailableRoles: MockRoles.getAllRoles.bind(MockRoles),
  hasRole: MockRoles.hasRole.bind(MockRoles),
  hasAnyRole: MockRoles.hasAnyRole.bind(MockRoles),
  resetRole: MockRoles.resetRole.bind(MockRoles),
  
  // 调试模式
  enableDebugMode: MockRoles.enableDebugMode.bind(MockRoles),
  disableDebugMode: MockRoles.disableDebugMode.bind(MockRoles),
  isDebugMode: MockRoles.isDebugModeEnabled.bind(MockRoles),
  isDebugModeEnabled: MockRoles.isDebugModeEnabled.bind(MockRoles),
  
  // 权限检查
  hasPermission: MockRoles.hasPermission.bind(MockRoles),
  
  // 辅助函数
  _getRoleName: MockRoles._getRoleName.bind(MockRoles),
  getRoleName: MockRoles._getRoleName.bind(MockRoles),
  clearLogs: MockRoles.clearLogs.bind(MockRoles),
  
  // 配置访问
  setConfig: function(config) {
    Object.assign(MockRoles.config, config);
  },
  
  getConfig: function() {
    return { ...MockRoles.config };
  },
  
  // 新增方法
  getSimulatedRole: MockRoles.getSimulatedRole.bind(MockRoles),
  getSimulatedRoleInfo: MockRoles.getSimulatedRoleInfo.bind(MockRoles),
  createTestProject,
  setSimulatedRole,
}; 